﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace Slam
{
	public class SlamAction
	{
		private Action<SPListItem> _action;
		public Action<SPListItem> Action
		{
			get
			{
				return _action;
			}
		}

		private SlamEvent _event;
		public SlamEvent Event
		{
			get
			{
				return _event;
			}
		}

		private int _executionOrder;
		public int ExecutionOrder
		{
			get
			{
				return _executionOrder;
			}
		}
		
		private string _id;
		public string Id
		{
			get
			{
				return _id;
			}
		}

		private bool _synchronous;
		public bool Synchronous
		{
			get
			{
				return _synchronous;
			}
		}

		public SlamAction(Action<SPListItem> action) :
			this(action, Constants.DefaultActionExecutionOrder)
		{	
		}

		public SlamAction(Action<SPListItem> action, int executionOrder) :
			this(action, executionOrder, SlamEvent.PostSave)
		{	
		}

		public SlamAction(Action<SPListItem> action, int executionOrder, SlamEvent slamEvent) :
			this(action.Method.Name + Convert.ToBase64String(action.Method.GetMethodBody().GetILAsByteArray()), action, executionOrder, slamEvent)
		{
		}

		public SlamAction(string id, Action<SPListItem> action, int executionOrder, SlamEvent slamEvent) :
			this(id, action, executionOrder, slamEvent, true)
		{	
		}

		public SlamAction(string id, Action<SPListItem> action, int executionOrder, SlamEvent slamEvent, bool synchronous)
		{
			_id = id;
			_action = action;
			_executionOrder = executionOrder;
			_event = slamEvent;
			_synchronous = synchronous;
		}

		public void Execute(SPListItem listItem)
		{
			if (Synchronous)
				Action.Invoke(listItem);
			else
				Action.BeginInvoke(listItem, ExecuteCallback, Action);
		}

		public void ExecuteCallback(IAsyncResult result)
		{
			Action<SPListItem> action = (Action<SPListItem>)result.AsyncState;
			action.EndInvoke(result);
		}
	}
}
